#ifndef CTOR_HELPER_HPP
#define CTOR_HELPER_HPP

#include <boost/interprocess/managed_shared_memory.hpp>

namespace rpc_monitor{

namespace bi=boost::interprocess;

template <typename ST, typename CT, typename R=ST>
struct ctor_helper{
	ST m_t;
	template <typename ...Args>
	ctor_helper(const char *p_name, const Args&... p_args) : m_t(CT(), p_name, p_args...) {};
	~ctor_helper() {};
};

template <typename ST, typename R>
struct ctor_helper<ST, bi::create_only_t, R>{
	ST m_t;
	std::string m_name;
	template <typename ...Args>
	ctor_helper(const char *p_name, const Args&... p_args) : m_t(bi::create_only_t(), p_name, p_args...), m_name(p_name) {};
	~ctor_helper() { R::remove(m_name.c_str()); };
};

template <typename ST, typename CT>
struct ctor_helper<ST *, CT, ST *>{
	ST *m_t;
	template <typename ...Args>
	ctor_helper(bi::managed_shared_memory &p_memory, const Args&... p_args){
		m_t = p_memory.find<ST>(bi::unique_instance).first;
	};
};


template <typename ST>
struct ctor_helper<ST *, bi::create_only_t, ST *>{
	ST *m_t;
	bi::managed_shared_memory &m_memory;
	template <typename ...Args>
	ctor_helper(bi::managed_shared_memory &p_memory, const Args&... p_args) : m_memory(p_memory){
		m_t = m_memory.construct<ST>(bi::unique_instance)(p_args...);
	};
	~ctor_helper(){
		m_memory.destroy_ptr(m_t);
	};
};

}

#endif /* #ifndef CTOR_HELPER_HPP */

